Skip to content

Method: handleSingularReferenceNode(JsonObject, Class)

1: /*
2: * JB4JSON-LD
3: * Copyright (C) 2023 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.jsonld.deserialization.expanded;
19:
20: import cz.cvut.kbss.jsonld.JsonLd;
21: import cz.cvut.kbss.jsonld.deserialization.DeserializationContext;
22: import cz.cvut.kbss.jsonld.deserialization.InstanceBuilder;
23: import cz.cvut.kbss.jsonld.deserialization.util.DataTypeTransformer;
24: import cz.cvut.kbss.jsonld.deserialization.util.LangString;
25: import cz.cvut.kbss.jsonld.deserialization.util.ValueUtils;
26: import cz.cvut.kbss.jsonld.deserialization.util.XSDTypeCoercer;
27: import cz.cvut.kbss.jsonld.exception.MissingIdentifierException;
28: import jakarta.json.JsonArray;
29: import jakarta.json.JsonObject;
30: import jakarta.json.JsonValue;
31:
32: import java.net.URI;
33:
34: class CollectionDeserializer extends Deserializer<JsonArray> {
35:
36: private final String property;
37:
38: CollectionDeserializer(InstanceBuilder instanceBuilder, DeserializerConfig config, String property) {
39: super(instanceBuilder, config);
40: this.property = property;
41: }
42:
43: @Override
44: void processValue(JsonArray value) {
45: if (value.size() == 1 && value.get(0).getValueType() == JsonValue.ValueType.OBJECT) {
46: final JsonObject obj = value.getJsonObject(0);
47: if (!instanceBuilder.isPlural(property)) {
48: resolvePropertyValue(obj);
49: return;
50: }
51: if (obj.size() == 1 && obj.containsKey(JsonLd.LIST)) {
52: assert obj.get(JsonLd.LIST).getValueType() == JsonValue.ValueType.ARRAY;
53: processValue(obj.getJsonArray(JsonLd.LIST));
54: return;
55: }
56: }
57: instanceBuilder.openCollection(property);
58: for (JsonValue item : value) {
59: if (item.getValueType() == JsonValue.ValueType.OBJECT) {
60: resolveValue(item.asJsonObject());
61: } else {
62: instanceBuilder.addValue(ValueUtils.literalValue(item));
63: }
64: }
65: instanceBuilder.closeCollection();
66: }
67:
68: private void resolveValue(JsonObject value) {
69: final Class<?> targetType = instanceBuilder.getCurrentCollectionElementType();
70: if (config.getDeserializers().hasCustomDeserializer(targetType)) {
71: instanceBuilder.addValue(deserializeUsingCustomDeserializer(targetType, value));
72: } else if (value.size() == 1 && value.containsKey(JsonLd.VALUE)) {
73: instanceBuilder.addValue(ValueUtils.literalValue(ValueUtils.getValue(value)));
74: } else if (value.size() == 1 && value.containsKey(JsonLd.ID)) {
75: handleReferenceNodeInCollection(value, targetType);
76: } else if (value.containsKey(JsonLd.LANGUAGE)) {
77: assert value.containsKey(JsonLd.VALUE);
78: instanceBuilder.addValue(
79: new LangString(ValueUtils.stringValue(ValueUtils.getValue(value)), ValueUtils.stringValue(value.get(JsonLd.LANGUAGE))));
80: } else if (instanceBuilder.isCurrentCollectionProperties()) {
81: // If we are deserializing an object into @Properties, just extract the identifier and put it into the map
82: if (!value.containsKey(JsonLd.ID)) {
83: throw new MissingIdentifierException(
84: "Cannot put an object without an identifier into @Properties. Object: " + value);
85: }
86: instanceBuilder.addValue(URI.create(ValueUtils.stringValue(value.get(JsonLd.ID))));
87: } else {
88: final Class<?> elementType = instanceBuilder.getCurrentCollectionElementType();
89: new ObjectDeserializer(instanceBuilder, config, elementType).processValue(value);
90: }
91: }
92:
93: private void handleReferenceNodeInCollection(JsonObject value, Class<?> targetType) {
94: assert value.size() == 1 && value.containsKey(JsonLd.ID);
95: final String identifier = ValueUtils.stringValue(value.get(JsonLd.ID));
96: if (targetType.isEnum()) {
97: instanceBuilder.addValue(DataTypeTransformer.transformIndividualToEnumConstant(identifier,
98: (Class<? extends Enum>) targetType));
99: } else {
100: instanceBuilder.addNodeReference(identifier);
101: }
102: }
103:
104: private void resolvePropertyValue(JsonObject value) {
105: final Class<?> targetType = instanceBuilder.getTargetType(property);
106: if (config.getDeserializers().hasCustomDeserializer(targetType)) {
107: instanceBuilder.addValue(property, deserializeUsingCustomDeserializer(targetType, value));
108: return;
109: }
110: if (value.containsKey(JsonLd.VALUE)) {
111: extractLiteralValue(value);
112: } else if (value.size() == 1 && value.containsKey(JsonLd.ID)) {
113: handleSingularReferenceNode(value, targetType);
114: } else {
115: new ObjectDeserializer(instanceBuilder, config, property).processValue(value);
116: }
117: }
118:
119: private <T> T deserializeUsingCustomDeserializer(Class<T> targetType, JsonObject value) {
120: final DeserializationContext<T> ctx = new DeserializationContext<>(targetType, config.getTargetResolver());
121: assert config.getDeserializers().getDeserializer(ctx).isPresent();
122: return config.getDeserializers().getDeserializer(ctx).get().deserialize(value, ctx);
123: }
124:
125: private void extractLiteralValue(JsonObject value) {
126: final JsonValue val = value.get(JsonLd.VALUE);
127: if (value.containsKey(JsonLd.TYPE)) {
128: instanceBuilder
129: .addValue(property, XSDTypeCoercer.coerceType(ValueUtils.stringValue(val), ValueUtils.stringValue(value.get(JsonLd.TYPE))));
130: } else if (value.containsKey(JsonLd.LANGUAGE)) {
131: instanceBuilder.addValue(property, new LangString(ValueUtils.stringValue(val), ValueUtils.stringValue(value.get(JsonLd.LANGUAGE))));
132: } else {
133: instanceBuilder.addValue(property, ValueUtils.literalValue(val));
134: }
135: }
136:
137: private void handleSingularReferenceNode(JsonObject value, Class<?> targetType) {
138:• assert value.size() == 1 && value.containsKey(JsonLd.ID);
139: final String identifier = ValueUtils.stringValue(value.get(JsonLd.ID));
140:• if (targetType.isEnum()) {
141: instanceBuilder.addValue(property, DataTypeTransformer.transformIndividualToEnumConstant(identifier,
142: (Class<? extends Enum>) targetType));
143: } else {
144: instanceBuilder.addNodeReference(property, identifier);
145: }
146: }
147: }